<?php

/*
\p{Ll}  G_UNICODE_LOWERCASE_LETTER
\p{Lt}  G_UNICODE_TITLECASE_LETTER
\p{Lu}  G_UNICODE_UPPERCASE_LETTER
\p{Lo}  G_UNICODE_OTHER_LETTER
\p{Lm}  G_UNICODE_MODIFIER_LETTER
  
     L& = Ll, Lu, Lt
     L  = L&, Lo, Lm
  
\p{Mc}  G_UNICODE_COMBINING_MARK
\p{Me}  G_UNICODE_ENCLOSING_MARK
\p{Mn}  G_UNICODE_NON_SPACING_MARK
  
     M = Mc, Me, Mn
  
\p{Nd}  G_UNICODE_DECIMAL_NUMBER
\p{Nl}  G_UNICODE_LETTER_NUMBER
\p{No}  G_UNICODE_OTHER_NUMBER

     N = Nd, Nl, No

\p{Pc}  G_UNICODE_CONNECT_PUNCTUATION

----------------------------------

Suffix:
' (&amp;)
\p{Pd}  G_UNICODE_DASH_PUNCTUATION

regex: "[\p{L}\p{M}\p{Pc}]+['\p{Pc}]*"
*/


// define("UNICODE_WORD_REGEX", 
// "[\p{L}\p{M}\p{N}\p{Pc}][\p{L}\p{M}\p{N}\p{Pc}\p{Pd}']*[\p{L}\p{M}\p{N}\p{Pc}\p{Pd}]");
define("UNICODE_WORD_NUMBER_REGEX", 
     "[\p{L}\p{M}\p{N}\p{Pc}]"        // letter or digit or connector
    ."[\p{L}\p{M}\p{N}\p{Pc}\p{Pd}']+"); // ... or dash-punctuation

define("UNICODE_WORD_REGEX", 
"[\p{L}\p{M}\p{N}\p{Pc}][\p{L}\p{M}\p{N}\p{Pc}\p{Pd}']*[\p{L}\p{M}\p{N}\p{Pc}\p{Pd}]");

//     "[\p{L}\p{M}\p{Pc}][\p{L}\p{M}\p{Pc}\p{Pd}']+");

// define("UNICODE_WORD_DELIMITER", "[^\p{L}\p{M}\p{N}\p{Pc}\-{Pd}]");
define("UNICODE_WORD_DELIMITER", "[^\p{L}\p{M}\p{Pc}\-{Pd}]");
define("UWR", UNICODE_WORD_REGEX);
define("UWD", UNICODE_WORD_DELIMITER);

class DpEnchantedWords  {
    // fully composed word => array( line ... )
    private $_words;
    private $_text;
    private $_input;
    private $_raw;
    private $_words_lines;
    private $_cmd;

    /*
        /var/transient/enchant/
    */

    public function __construct($langcode, $text, $projectid = "") {
        // $text = uppercase($text);
        $this->_text = $text;

        // /var/transient/enchant/
        $wcpath = $this->transient_directory();

        // /var/transient/enchant/.de.enchant.txt#####
        $txtpath = build_path($wcpath, 
                        "{$projectid}.{$langcode}.enchant.txt");
        $txtpath = tempnam($wcpath, $txtpath);

        // /var/transient/enchant/.de.enchant.cmd
        // $cmdpath = build_path($wcpath, 
          //   "{$projectid}.{$langcode}.enchant.cmd");
        // $cmdpath = tempnam($wcpath, $cmdpath);

        // /var/transient/enchant/.de.enchanted.txt%%%%%%%%
        // $enchpath = build_path($wcpath, 
                        // "{$projectid}.{$langcode}.enchanted.txt");
        // $enchpath = tempnam($wcpath, $enchpath);

        
        file_put_contents($txtpath, $text);
        $this->_cmd = "enchant -L -l -d $langcode $txtpath";
        // file_put_contents($cmdpath, $this->_cmd);
        // execute enchant and save raw output - (line word)
        // $this->_enchanted_raw = shell_exec($this->_cmd);
        $enchanted = shell_exec($this->_cmd);
        // say("1 ".mb_strlen($enchanted));
        // file_put_contents($enchpath.".1", $this->_enchanted_raw);

        unlink($txtpath);

        // lower-case it
        $this->_raw = $enchanted;
        // file_put_contents($enchpath.".2", $enchanted);

        // dump no-words
        // dump numbers
        $enchanted = ReplaceRegex("^[\d\s\p{Pd}]*$", "", "um", $enchanted);
        // $enchanted = ReplaceRegex("^\d+\s(\D+\d|]d+\D).*?$", "", "um", $enchanted);
        // dump($enchanted);
        // $enchanted = preg_replace("~^\d+\s.*?\d.*?$~um", "", $enchanted);

        // convert it to array and store widgets in _words_lines
        $tl = array_diff(text_lines($enchanted), array(""));
        // say("0.0 ".count($tl));
        // $tl = array_diff($tl, array(""));
        // say("0.1 ".count($tl));
        // $this->set_words_lines($tl);
        $this->_words_lines = array();
        foreach($tl as $t) {
            list($l, $w) =  RegexSplit(" ", "u", $t);
            if(RegexCount("[\d\-\_]", "u", $w) == 0
                                    && mb_strlen($w) > 0) {
                $this->_words_lines[$w][] = $l;
            }
        }

        // remove no-words and words with digits
        // reduce line-space-word to just word
        // $ptn = array("/^[\d\s]*?$/um", // only digits and spaces
              // "/^\d+\s(\D*?)$/um", // good - digits, space, ...
                     // );
        // $rpl = array("", "$1");
        // $this->_enchanted = preg_replace($ptn, $rpl, $enchanted);
        // say("3 ".mb_strlen($enchanted));

        // $this->_enchanted = $enchanted;
        // file_put_contents($enchpath.".3", $this->_enchanted);

        // $etl = text_lines($enchanted);
        $this->_words = array_unique(array_diff($tl, array("")));
    }

    public function Input() {
        return $this->_text;
    }
    public function Command() {
        return $this->_cmd;
    }

    public function RawOutput() {
        return $this->_enchanted_raw;
    }

    private function transient_directory() {
        $dirpath = build_path(TRANSIENT_ROOT, "enchant");
        if(! file_exists($dirpath)) {
            mkdir($dirpath, 0777);
        }
        return $dirpath;
    }

/*
    private function _enchant_word_array($langcode, &$text) {
        // $enchantstr = _enchant_text($langcode, $text);
        $enchantlines = _enchant_lines($langcode, $text);
        $ptn = array("/^[\d\s]*$/m",
                     "/^\d+\s(.*)$/m");
        $rpl = array("", "$1");
        // return preg_replace($ptn, $rpl, $enchantstr);
        return preg_replace($ptn, $rpl, $enchantlines);
    }

    private function _enchant_lines($langcode, &$text) {
        $enchantstr = _enchant_text($langcode, $text);
        return text_lines($enchantstr);
    }
*/

    public function WordsArray() {
        $a = ReplaceRegex("\d+\s+(.*?)$", "$1", "u", $this->_words);
        natsort(array_values($a));
        return array_unique($a);
    }

/*
    protected function set_words_lines($tl) {
        $this->_words_lines = array();
        foreach($tl as $t) {
            list($l, $w) =  RegexSplit(" ", "u", $t);
            $this->_words_lines[$w][] = $l;
        }
    }
    
*/

    // transform word => array(lines) to array(word, line)
    public function WordLineArray() {
        $a = array();
        foreach($this->_words_lines as $word => $lines) {
            foreach($lines as $line) {
                $a[] = array($word, $line);
            }
        }
        return $a;
    }

    // transform word => array(lines) to array( word, array(lines))
    public function WordLinesArray() {
        $a = array();
        foreach($this->_words_lines as $word => $lines) {
            $a[] = array($word, $lines);
        }
        return $a;
    }

    function TextLines() {
        return text_lines($this->_text);
    }
}
?>
